#include <Game/Game.h>
#include <Entities/actor.h>
#include <include/sdk/misc.h>
#include "StatCheck.h"
#include "Skills/typeAttack.h"
#include "Skills/typeDefense.h"
#include "Skills/typeGather.h"
#include "include/sdk/stats.h"

namespace skill {
    bool ReCalculateStats::use(Game *g, const std::vector<std::string> &params) {
        auto plant = dynamic_cast<entity::Plant *>(origin);
        RobotType type = RobotType(std::stoi(plant->properties["type"]));
        int level = std::stoi(plant->properties["level"]);
        plant->properties["attack"] = std::to_string(stats::getAttack(level, type));
        plant->properties["max_hp"] = std::to_string(stats::getMaxHP(level, type));
        plant->properties["defense"] = std::to_string(stats::getDefense(level, type));
        double overloadCheck = 1.0;
        if (plant->hasSkill("OverloadHighBuff")) overloadCheck *= 2;
        if (plant->hasSkill("OverloadLowBuff")) overloadCheck *= 0.5;
        plant->properties["consumption"] = std::to_string(int(overloadCheck * stats::getConsumption(level)));
        plant->properties["efficiency"] = std::to_string(int(overloadCheck * stats::getEfficiency(level, type)));
        plant->properties["transport_capacity"] = std::to_string(stats::getCapacity(level, type));
        return Skill::use(g, params);
    }

    void removeSkillIfHave(Entity *origin, std::string skillName) {
        if (origin->hasSkill(skillName)) {
            origin->unlearnSkill(origin->skillList[skillName]);
        }
    }

    bool ValidateSkills::use(Game *g, const std::vector<std::string> &params) {
        int type = stoi(origin->properties["type"]);
        if (type == RobotType::AttackRobot) {
            origin->learnSkill(new Bombing);
            origin->learnSkill(new Scourge);
        } else {
            removeSkillIfHave(origin, "Scourge");
            removeSkillIfHave(origin, "Bombing");
        }
        if (type == RobotType::DefenseRobot) {
            origin->learnSkill(new Recover);
            origin->learnSkill(new Shielding);
        } else {
            removeSkillIfHave(origin, "Recover");
            removeSkillIfHave(origin, "Shielding");
        }
        if (type == RobotType::GatherRobot){
            origin->learnSkill(new Airborne);
            origin->learnSkill(new Overload);
        } else {
            removeSkillIfHave(origin, "Airborne");
            removeSkillIfHave(origin, "Overload");
        }
        return Skill::use(g, params);
    }


    bool AutoRecovery::use(Game *g, const std::vector<std::string> &params) {
        int now_energy = stoi(origin->properties["energy"]);
        int energy_consumption = stoi(origin->properties["consumption"]);
        int max_hp = stoi(origin->properties["max_hp"]);
        int now_hp = stoi(origin->properties["hp"]);
        if ((now_energy >= energy_consumption)) {
            now_energy -= energy_consumption;
            origin->properties["hp"] = std::to_string(int(now_hp + max_hp * RecoveryHPRate + EPS));
        } else {
            now_energy = 0;
            origin->properties["hp"] = std::to_string(int(now_hp + max_hp * WitherHPRate + EPS));
        }
        origin->properties["energy"] = std::to_string(now_energy);
        return Skill::use(g, params);
    }
}